import router, { asyncRoutes } from './router'
import { getToken } from '@/utils/auth'
import store from '@/store'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import getPageTitle from '@/utils/get-page-title'

const noTokenRouteList = ['/login','/404'] // 白名单

// 跳转前
router.beforeEach(async (to, from, next) => {
  NProgress.start()
  // 登录了 > 不能去登录页
  // 非登录 > 只能去登录页 / 404
    if(getToken()){ // 登录了
      if(to.path == '/login'){ // 去登录页
      // 中断要跳转 /login 这次导航,重新跳转到首页
        next('/')
        NProgress.done()
      }else{ // 登录后,去别的页面
        next()
        // 判断有无用户个人信息,防止用户一开始进入的不是首页发起不了获取用户信息的请求,每次刷新或切换页面都会进入到这里进行判断
        if(!store.getters.name){
          // menus是后台返回的该角色应有的权限菜单
          const menus = await store.dispatch('user/getUserInfoActions') // 发起请求
          let filterAsignRole = asyncRoutes.filter(routeObj => { // 循环动态路由
              let routeName = routeObj.children[0].name.toLowerCase() // 取每个路由的名字
              return menus.includes(routeName) // 跟后台返回的权限菜单作比较,结果为true即返回当前对象作为 filter 的本次结果
          })
          // filterAsignRole为最终筛选后对比的结果
          /*
            始终都动态添加先,8个路由规则对象
            知识点: 路由切换匹配的路由规则对象数组存在于内存中
            new Router时,有一些初始的路由规则对象
            addRoutes, 会给路由表,再额外的增加一个规则对象
            现象: 路由规则对象添加成功,但是左侧的导航不见了
          */
         /*
            问题: 为何动态路由添加后,在动态路由地址上刷新会 404
            前提1: 刷新时,所有代码会重新执行
            前提2: 刷新时,路由会从 / 跳转到浏览器地址栏所在的路由地址(就是 dashboard),进入路由守卫
                   判断有 cookie,去非login页面,然后放行,放行后发现该动态路由地址还没有添加进去 vuex 动态数组里面
                   只能走兜底的 404 页面

            解决:
                  1 把 404 兜底页面从静态路由中移除
                  2 在动态路由页面刷新页面,进入放行后因为匹配不到动态路由,此时会白屏,
                  3 此时会走入路由守卫,重新发起获取用户信息的请求,因为刷新后代码会重新执行
                  4 在过滤完后台和动态路由的筛选后,push 一个404页面进入过滤好的数组
                  5 给 vuex,给当前 VueRouter 各自添加一份筛选后的路由表(vuex是实时响应式渲染左侧导航栏用的,VueRouter是匹配 url 规则时用的)
                  6 此时已执行完动态路由添加,但是页面还是白屏状态,需要手动调用next()函数
                    重新再加载本页面一次即可
         */
          filterAsignRole.push({ path: '*', redirect: '/404', hidden: true }) // 动态添加一个兜底404
          router.addRoutes(filterAsignRole) // 添加一份非响应式的数组(用来 url 匹配规则使用),添加后 route.options并看不见
          store.commit('permission/asignRole',filterAsignRole) // 添加一份响应式的数组(左侧导航栏遍历使用)
          // 路由再跳转一次,因为上面 next() , 会导致白屏(因为放行时,动态路由还没有加入到内存中路由表里)
          // 添加完,再跳转一次
          next({
            path: to.path,
            replace: true , // 不让回退 === this.$router.replace
          })
          // console.log(filterAsignRole)
        }
      }
    }else{ // 没有登录
      if(noTokenRouteList.includes(to.path)){ // 要去的路由地址字符串,是否在白名单数组里出现过,出现过就放行
        next()
      }else{ // 不登录去别的页面(不能去)
        next('/login')
        NProgress.done()
      }
    }
})

// 跳转完
router.afterEach((to,from) => {
  document.title = getPageTitle(to.meta.title)
  NProgress.done()
})
